package com.baitiaojun.video.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baitiaojun.api.domain.user.UserCoin;
import com.baitiaojun.api.domain.video.Video;
import com.baitiaojun.api.domain.video.VideoCoin;
import com.baitiaojun.api.domain.video.VideoOperation;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.util.SnowFlakeUtil;
import com.baitiaojun.api.vo.JsonRes;
import com.baitiaojun.api.vo.LikeCoinOperatedCollectedInfo;
import com.baitiaojun.video.feign.UserFeign;
import com.baitiaojun.video.mapper.VideoCoinMapper;
import com.baitiaojun.video.mapper.VideoOperationMapper;
import com.baitiaojun.video.service.VideoCoinService;
import com.baitiaojun.video.service.VideoLikeService;
import com.baitiaojun.video.service.VideoService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @类名 VideoCoinServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2022/12/25 16:43
 * @版本 1.0
 */
@Service
public class VideoCoinServiceImpl implements VideoCoinService {

    @Autowired
    private UserFeign userFeign;

    @Resource
    private VideoCoinMapper videoCoinMapper;

    @Autowired
    private VideoService videoService;

    @Resource
    private VideoOperationMapper videoOperationMapper;

    @Autowired
    private VideoLikeService videoLikeService;

    @GlobalTransactional
    @Override
    public void addVideoCoin(Long userId, Long videoId, Integer coinOperated, String token) throws ConditionException, InterruptedException {
        //根据videoid查看视频是否存在
        Integer isExists = videoService.isExistsVideo(videoId);
        if (ObjectUtils.isEmpty(isExists)) {
            throw new ConditionException("该视频不存在");
        }
        //根据userid查看用户拥有的硬币数量
        Object data = userFeign.getUserCoin(userId).get("data");
        if (ObjectUtils.isEmpty(data)) {
            throw new ConditionException("无法获取用户拥有的硬币数量");
        }
        int amount = Integer.parseInt(JSONObject.toJSONString(data));
        //如果硬币数量不为空,就判是否有足够硬币数量对视频投币
        if (coinOperated > amount) {
            throw new ConditionException("没有足够的硬币");
        }
        //用户不能给自己投币
        Long uId = videoService.getUserIdByVideoId(videoId);
        if (ObjectUtils.isNotEmpty(uId) && userId.equals(uId)) {
            throw new ConditionException("投币失败，up主不能给自己投币~");
        }
        //根据userid和videoid查询当前用户是否已经对这个视频投过币
        boolean isCoinOperated = Objects.isNull(videoCoinMapper.isCoinOperated(userId, videoId));
        //没有投过币就新增投币记录，如果投过币就不允许再次投币
        if (isCoinOperated) {
            int res = videoCoinMapper.insertSelective(
                    VideoCoin.builder()
                            .id(SnowFlakeUtil.getNextId())
                            .amount(coinOperated)
                            .userid(userId)
                            .videoid(videoId)
                            .createtime(new Date()).build());
            if (res == 0) {
                throw new ConditionException("投币失败");
            }
        } else {
            throw new ConditionException("已超出投币上限");
        }
        //添加视频投币操作记录
        VideoOperation videoOperation = new VideoOperation();
        videoOperation.setId(SnowFlakeUtil.getNextId());
        videoOperation.setUserid(userId);
        videoOperation.setVideoid(videoId);
        videoOperation.setCreatetime(new Date());
        videoOperation.setOperationtype(ConstantUtil.OPERATION_TYPE_COIN_OPERATED);
        int resVideoOperation = videoOperationMapper.insertSelective(videoOperation);
        if (resVideoOperation == 0) {
            throw new ConditionException("添加视频投币操作记录失败");
        }
        //更新当前用户硬币总数
        JsonRes jsonRes = userFeign.updateUserCoin(UserCoin.builder()
                .userid(userId)
                .amount((long) (amount - coinOperated))
                .updatetime(new Date()).build(), token);
        if (jsonRes.get("status").equals(500)) {
            throw new ConditionException("用户硬币更新失败");
        }
        //完成一行操作进行该视频的点赞操作
        LikeCoinOperatedCollectedInfo videoLike = videoLikeService.getVideoLike(userId, videoId);
        if (Boolean.FALSE.equals(videoLike.get("like"))) {
            videoLikeService.addVideoLike(videoId, userId);
        }
    }

    @Override
    public LikeCoinOperatedCollectedInfo getVideoCoin(Long videoId, Long userId) {
        Integer count = videoCoinMapper.selectVideoCoinCount(videoId);
        Integer isCoinOperated = null;
        if (ObjectUtils.isNotEmpty(userId)) {
            isCoinOperated = videoCoinMapper.isCoinOperated(userId, videoId);
        }
        return LikeCoinOperatedCollectedInfo.builder()
                .count(ObjectUtils.isEmpty(count)?0:count)
                .flag("coinOperated", ObjectUtils.isNotEmpty(isCoinOperated)).build();
    }

    @Override
    public Integer getVideoCoinCount(Long videoId) {
        return videoCoinMapper.selectVideoCoinCount(videoId);
    }
}